﻿//using System;
//using System.Diagnostics;
//using System.Collections.Generic;
//using System.Text;
//using StockGeneral;

//namespace IciciDirect
//{

//    // BUGBUGD: Is this class really required ? Will it be required anyway in the design anytime ?
//    // All info about stock is generic into the base class EquityStockInformation
//    // This class is never usd as of now
//    public sealed class IciciEquityStockInformation : EquityStockInformation
//    {
//        // Constructor 

//        public IciciEquityStockInformation(string stockCode) : base (stockCode) { }

//        public IciciEquityStockInformation(string stockCode, 
//            double fundLimitStarting, 
//            int stockAvailableStarting,
//            Exchange mainExchange,
//            double lossLimit,
//            double brokerageRate,
//            double minBrokerage) :
//        base (stockCode, 
//            fundLimitStarting, 
//            stockAvailableStarting,
//            mainExchange,
//            lossLimit,
//            brokerageRate,
//            minBrokerage)
//        {
//            mBrokerageRate = brokerageRate;
//            mMinBrokerage = minBrokerage;
//        }

//        public void SetEquityStockParams(string stockCode,
//            double fundLimitStarting, 
//            int stockAvailableStarting,
//            Exchange mainExchange,
//            double lossLimit,
//            double brokerageRate,
//            double minBrokerage)
//        {
//            StockCode = stockCode;
//            FundLimitAtStart = fundLimitStarting;
//            StockAvailableAtStart = stockAvailableStarting;
//            MainExchange = mainExchange;
//            LossLimit = lossLimit;
//            mBrokerageRate = brokerageRate;
//            mMinBrokerage = minBrokerage;
//            ResetDynamicValues();
//        }


//        private double mBrokerageRate = 0;
//        private double mMinBrokerage = 0;

//        private object lockStateObject = new object();

//        // Outstanding Orders and Trades list
//        private Dictionary<string, EquityTradeBookStockElement> mTrades = new Dictionary<string, EquityTradeBookStockElement>();
//        private Dictionary<string, EquityOrderBookStockElement> mOutstandingOrders = new Dictionary<string, EquityOrderBookStockElement>();
//        private Dictionary<string, EquityOrderBookStockElement> mOutstandingBuyOrders = new Dictionary<string, EquityOrderBookStockElement>();
//        private Dictionary<string, EquityOrderBookStockElement> mOutstandingSellOrders = new Dictionary<string, EquityOrderBookStockElement>();

//        public Dictionary<string, EquityTradeBookStockElement> Trades
//        {
//            get { lock (lockStateObject) { return mTrades; } }
//            private set { lock (lockStateObject) { mTrades = value; } }
//        }
//        public Dictionary<string, EquityOrderBookStockElement> OutstandingOrders
//        {
//            get { lock (lockStateObject) { return mOutstandingOrders; } }
//            private set { lock (lockStateObject) { mOutstandingOrders = value; } }
//        }
//        public Dictionary<string, EquityOrderBookStockElement> OutstandingBuyOrders
//        {
//            get { lock (lockStateObject) {return mOutstandingBuyOrders; }}
//            private set { lock (lockStateObject) { mOutstandingBuyOrders = value; } }
//        }
//        public Dictionary<string, EquityOrderBookStockElement> OutstandingSellOrders
//        {
//            get { lock (lockStateObject) { return mOutstandingSellOrders; } }
//            private set { lock (lockStateObject) { mOutstandingSellOrders = value; } }
//        }

//        private int mNumTrades;
//        public int NumTrades
//        {
//            get { lock (lockStateObject) { return mNumTrades; } }
//            private set { lock (lockStateObject) { mNumTrades = value; } }
//        }

//        private int mNumOrders;
//        public int NumOrders
//        {
//            get { lock (lockStateObject) { return mNumOrders; } }
//            private set { lock (lockStateObject) { mNumOrders = value; } }
//        }


//        //public PlaceDeliveryOrder()
//        //{


//        //}


//        // TODO: take into account same day buy sell brokerage
//        public double EstimatedBrokerage(double transactionAmt)
//        {
//            return (Math.Max(transactionAmt * mBrokerageRate, mMinBrokerage));
//        }


//        // State values updated as non-incremental (i.e. each time whole of tradebook and orderbook are parsed)
//        // Taking into account all trades, trade state variables are updated
//        // then taking all outstanding orders, order state variables are updated 

//        // NOTE: ordering of TRADE update before ORDER update is required because trades (profit :-) )
//        // may have modified the FundLimitCurrent which is basically the limit available for orders
//        public BrokerErrorCode RefreshState(Dictionary<string, EquityOrderBookStockElement> orders,
//            Dictionary<string, EquityTradeBookStockElement> trades)
//        {
//            if (orders == null || trades == null)
//            {
//                return BrokerErrorCode.InValidArg;
//            }

//            BrokerErrorCode errorCode = BrokerErrorCode.Success;

//            // lock for integrity of all STATE variable set [TODO: redundant lock, may remove]
//            lock (lockStateObject)
//            {
//                // None of the properties should be accessed when they are getting updated 
//                // as part of the state refresh, so hold the properties lock
//                lock (lockObjectProperties)
//                {
//                    // reassign the new order and trade books
//                    OutstandingOrders = orders;
//                    Trades = trades;

//                    // Reset the dynamic values
//                    ResetDynamicValues();
                    
//                    NumTrades = Trades.Count;

//                    // Update the Trade values
//                    foreach (KeyValuePair<string, EquityTradeBookStockElement> tradePair in Trades)
//                    {
//                        EquityTradeBookStockElement tradeInfo = tradePair.Value;

//                        if (tradeInfo.Direction == OrderDirection.BUY)
//                        {
//                            // Buy trades
//                            // Quantity
//                            TradeQtyBought += tradeInfo.Quantity;
//                            StockAvailableCurrent += tradeInfo.Quantity;

//                            // Trade or Estimated Brokerage
//                            double tradeBrokerage = tradeInfo.Brokerage == 0 ? EstimatedBrokerage(tradeInfo.TradeValue) : tradeInfo.Brokerage;
//                            TradeBrokerage += tradeBrokerage;

//                            // Funds limit
//                            FundLimitCurrent = FundLimitCurrent - tradeInfo.TradeValue - tradeBrokerage;
//                            string traceString = "FundLimitCurrent should never go below ZERO";
//                            Debug.Assert(FundLimitCurrent >= 0, traceString);
//                            GeneralUtils.TraceOut(FundLimitCurrent < 0, traceString);
//                        }
//                        else
//                        {
//                            // Sell Trades
//                            // Quantity
//                            TradeQtySold += tradeInfo.Quantity;
//                            StockAvailableCurrent -= tradeInfo.Quantity;
//                            string traceString = "StockAvailableCurrent should never go below ZERO";
//                            Debug.Assert(StockAvailableCurrent >= 0, traceString);
//                            GeneralUtils.TraceOut(StockAvailableCurrent < 0, traceString);

//                            // Trade or Estimated Brokerage
//                            double tradeBrokerage = tradeInfo.Brokerage == 0 ? EstimatedBrokerage(tradeInfo.TradeValue) : tradeInfo.Brokerage;
//                            TradeBrokerage += tradeBrokerage;

//                            // Funds limit
//                            FundLimitCurrent = FundLimitCurrent + tradeInfo.TradeValue - tradeBrokerage;
//                            traceString = "FundLimitCurrent should never go below ZERO";
//                            Debug.Assert(FundLimitCurrent >= 0, traceString);
//                            GeneralUtils.TraceOut(FundLimitCurrent < 0, traceString);    
//                        }

//                        // TODO: calculate brokerage properly for same day buy/sell trades
//                    }

//                    // HACKHACK: Dependency of Order limit values on Trade limit values being updated above 
//                    OrderFundLimit = FundLimitCurrent;
//                    OrderStockAvailable = StockAvailableCurrent;


//                    // Also maintain the buy and sell outstanding orders separately
//                    OutstandingBuyOrders.Clear();
//                    OutstandingSellOrders.Clear();

//                    NumOrders = OutstandingOrders.Count;

//                    // Update the order values
//                    foreach (KeyValuePair<string, EquityOrderBookStockElement> orderPair in OutstandingOrders)
//                    {
//                        EquityOrderBookStockElement orderInfo = orderPair.Value;

//                        if (orderInfo.Direction == OrderDirection.BUY)
//                        {
//                            // Buy orders

//                            OutstandingBuyOrders.Add(orderPair.Key, orderInfo);

//                            // Quantity
//                            OutstandingBuyQty += orderInfo.Quantity;
//                            //because these order stocks are not really available until the buy order executes
//                            //OrderStockAvailable += orderInfo.Quantity;

//                            // Order value
//                            double orderValue = orderInfo.Quantity * orderInfo.Price;

//                            // Estimated Brokerage
//                            double orderBrokerage = EstimatedBrokerage(orderValue);
//                            OrderBrokerage += orderBrokerage;

//                            // Funds limit
//                            OrderFundLimit = OrderFundLimit - orderValue - orderBrokerage;
//                            string traceString = "OrderFundLimit should never go below ZERO";
//                            Debug.Assert(OrderFundLimit >= 0, traceString);
//                            GeneralUtils.TraceOut(OrderFundLimit < 0, traceString);
//                        }
//                        else
//                        {
//                            // Sell orders

//                            OutstandingSellOrders.Add(orderPair.Key, orderInfo);

//                            // Quantity
//                            OutstandingSellQty += orderInfo.Quantity;
//                            OrderStockAvailable -= orderInfo.Quantity;
//                            string traceString = "OrderStockAvailable should never go below ZERO";
//                            Debug.Assert(OrderStockAvailable >= 0, traceString);
//                            GeneralUtils.TraceOut(OrderStockAvailable < 0, traceString);

//                            // Order value
//                            double orderValue = orderInfo.Quantity * orderInfo.Price;

//                            // Estimated Brokerage
//                            double orderBrokerage = EstimatedBrokerage(orderValue);
//                            OrderBrokerage += orderBrokerage;

//                            // Funds limit will reduce because of to-be-incurred brokerage 
//                            OrderFundLimit = OrderFundLimit - orderBrokerage;
//                            traceString = "OrderFundLimit should never go below ZERO";
//                            Debug.Assert(OrderFundLimit >= 0, traceString);
//                            GeneralUtils.TraceOut(OrderFundLimit < 0, traceString);
//                        }

//                    }
//                }
//            }
//            return errorCode;
//        } // Refresh state ends

//        public List<EquityOrderElement> ReturnFilteredValidOrders(List<EquityOrderElement> orders)
//        {
//            int numOrders = orders.Count;

//            List<EquityOrderElement> feasibleOrders = new List<EquityOrderElement>();

//            double orderFundLimit = OrderFundLimit;

//            // TODO: BUGBUG make types coherent all across
//            // some places we use uint for Quantity some places it is int
//            int orderStockAvailable = (int)OrderStockAvailable;

//            // Need to weed out and return only the feasible orders as per stock's stock/fund limit
//            for (int i = 0; i < numOrders; i++)
//            {
//                EquityOrderElement order = orders[i];
//                if (order.OrderDirection == OrderDirection.BUY)
//                {
//                    // Buy trades

//                    // Order value
//                    double price = 0;
//                    double orderValue = 0;

//                    if (double.TryParse(order.LimitPrice, out price))
//                    {
//                        orderValue = order.Quantity * price;
//                    }
//                    else
//                    {
//                        GeneralUtils.TraceOut("ReturnFilteredValidOrders: Could not parse order.LimitPrice");
//                        continue;
//                    }

//                    // Estimated Brokerage
//                    double brokerage = EstimatedBrokerage(orderValue);

//                    // Funds limit needed to fund this trade
//                    double fundsNeededForTrade = orderValue + brokerage;

//                    // If order limit is able to cover the order value (incl. brokerage) then it is a feasible order, add it
//                    if (orderFundLimit >= fundsNeededForTrade)
//                    {
//                        orderFundLimit -= fundsNeededForTrade;
//                        feasibleOrders.Add(order);
//                    }
//                }
//                else
//                {
//                    // Sell Trades

//                    // Order value
//                    double price = 0;
//                    double orderValue = 0;

//                    if (double.TryParse(order.LimitPrice, out price))
//                    {
//                        orderValue = order.Quantity * price;
//                    }
//                    else
//                    {
//                        GeneralUtils.TraceOut("ReturnFilteredValidOrders: Could not parse order.LimitPrice");
//                        continue;
//                    }

//                    // Estimated Brokerage
//                    double orderBrokerage = EstimatedBrokerage(orderValue);

//                    // If enough stocks are available to sell
//                    // and order limit is able to cover the brokerage costs then it is a feasible order, add it
//                    if (orderStockAvailable >= order.Quantity &&
//                        orderFundLimit >= orderBrokerage)
//                    {
//                        orderFundLimit -= orderBrokerage;
//                        orderStockAvailable -= order.Quantity;
//                        feasibleOrders.Add(order);
//                    }
//                }
//            }

//            return feasibleOrders;
//        } // ReturnFilteredValidOrders ends


//        // Is any outstanding buy or sell orders
//        public bool IsAnyOutstandingBuyOrder()
//        {
//            if (OutstandingBuyOrders.Count > 0)
//            {
//                return true;
//            }
//            return false;
//        }
//        public bool IsAnyOutstandingSellOrder()
//        {
//            if (OutstandingSellOrders.Count > 0)
//            {
//                return true;
//            }
//            return false;
//        }

//    }
//}
